#include "xen/renderer/renderer.hpp"

#include "platform/opengl/opengl_renderer_api.hpp"
#include "xen/renderer/renderer2d.hpp"
#include "xen/renderer/renderer3d.hpp"

namespace Xen {

RendererAPI::API Renderer::api_ = RendererAPI::API::None;
Renderer::SceneData Renderer::scene_data_;

void Renderer::init() {
    RenderCommand::Init();
}

void Renderer::Init(RendererAPI::API api) {
    if (api_ != RendererAPI::API::None) {
        XEN_CORE_ASSERT(false, "already have an API");
    }
    api_ = api;
    switch (api) {
        case RendererAPI::API::OpenGL:
            RenderCommand::renderer_api_ = new OpenGLRendererAPI;
            break;
        default:
            XEN_CORE_ASSERT(false, "Unknown API type");
    }
    init();
    Renderer2D::Init();
    Renderer3D::Init();
}

void Renderer::Shutdown() {
    Renderer3D::Shutdown();
    Renderer2D::Shutdown();
}

void Renderer::OnWindowResize(uint32_t w, uint32_t h) {
    RenderCommand::SetViewport(0, 0, w, h);
}

void Renderer::BeginScene(const OrthoCamera& camera) {
    scene_data_.project_view = camera.GetProjectViewMat();
}

void Renderer::BeginScene(const PerspectiveCamera& camera) {
    scene_data_.project_view = camera.GetProjectViewMat();
}

void Renderer::EndScene() {

}

void Renderer::Submit(const Ref<VertexArray>& vertex_array, const Ref<Shader>& shader, const glm::mat4& model) {
    shader->Bind();
    shader->UniformMat4("project_view", scene_data_.project_view);
    shader->UniformMat4("model", model);
    vertex_array->Bind();
    RenderCommand::DrawIndexed(vertex_array);
}

}
